package org.redhat.auth.security.resources.impl;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.redhat.auth.security.cache.ResourceCache;
import org.redhat.auth.security.data.DataModel;
import org.redhat.auth.security.resources.ResourceService;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.util.AntUrlPathMatcher;

/**
 * ResourceService的实现类
 * 
 * @author lingen.liu
 * 
 */
public class ResourceServiceImpl implements ResourceService {

	/* Resource的缓存管理 */
	private ResourceCache resourceCache;

	private DataModel dataModel;

	private AntUrlPathMatcher urlMatcher = new AntUrlPathMatcher();

	private final String RESOURCES_CACHE_EXISTS = "isResourcesCacheExists";

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		// 如果缓存不存在，则进行缓存
		if (!resourceCache.isResourceCacheExists()) {
			loadResources();
		}

		Collection<ConfigAttribute> cas = new HashSet<ConfigAttribute>();

		List<String> urls = resourceCache.getAllCacheUrls();
		urls.remove(RESOURCES_CACHE_EXISTS);
		for (String url : urls) {
			Collection<ConfigAttribute> ca = resourceCache.getResource(url);
			cas.addAll(ca);
		}

		return cas;
	}

	@Override
	/**
	 * 匹配原则,精确匹配
	 */
	public Collection<ConfigAttribute> getAttributes(String url) {
		// 如果缓存不存在，则进行缓存
		if (!resourceCache.isResourceCacheExists()) {
			loadResources();
		}

		Collection<ConfigAttribute> cas = null;
		/* 匹配前，对URL进行处理，去掉url中可能存在的url参数，只保留.action.jsp.html等以便进行精确匹配 */
		if (url.indexOf("?") != -1)
			url = url.substring(0, url.indexOf("?"));
		cas = resourceCache.getResource(url);
		return cas;
	}

	/**
	 * 初始化缓存数据
	 */
	@Override
	public void loadResources() {
		Map<String, Collection<ConfigAttribute>> resourceMap = dataModel
				.getResource();
		Set<String> urls = resourceMap.keySet();
		for (String url : urls) {
			resourceCache.putResourceCache(url, resourceMap.get(url));
		}
	}

	public ResourceCache getResourceCache() {
		return resourceCache;
	}

	public void setResourceCache(ResourceCache resourceCache) {
		this.resourceCache = resourceCache;
	}

	public DataModel getDataModel() {
		return dataModel;
	}

	public void setDataModel(DataModel dataModel) {
		this.dataModel = dataModel;
	}
}
